/*
 * thread.h
 *
 *  Created on: Aug 10, 2010
 *      Author: sdaniele
 */

#ifndef THREAD_H_
#define THREAD_H_

#include "process.h"

#include <boost/thread.hpp>

#include <assert.h>

namespace pilot {

	class thread: public pilot::process {
		public:
			virtual ~thread(){}
			thread()
				: m_is_first_call(true)
				, m_ready(false)
			{}

			void go(){
				if(m_is_first_call){
					m_is_first_call = false;
					start();
				}
				else
					resume();
			}

			void init(){
				m_me = boost::thread(start);
			}

			void start(){
				wait();
				this->operator();
			}

			void resume(){
				{
					boost::lock_guard<boost::mutex> lock(*m_mu);
					m_ready=true;
				}
				m_cond_1->notify_one();
				{
					boost::lock_guard<boost::mutex> lock(*m_mu);
					while(m_ready)
					{
						m_cond_1->wait(lock);
					}
				}
			}

			void wait(){
				boost::unique_lock<boost::mutex> lock(*m_mu);		//locks here
				while(!m_ready)
				{
					m_cond_1->wait(lock);		//unlocks here
				}
			}

			virtual void operator()(){assert(0);};
		private:
			boost::thread m_me;
			boost::condition_variable* m_cond_1;
			boost::condition_variable* m_cond_2;
			boost::mutex* m_mu;
			bool m_ready;
			bool m_is_first_call;
	};

}

#endif /* METHOD_H_ */
